﻿using System;
using System.Linq.Expressions;

namespace Cesave.Domain.Core.Specification
{
    /// <summary>
    /// Specificación lógica AND
    /// </summary>
    /// <typeparam name="T">Tipo de la entidad que checa ésta especificación.</typeparam>
    public class AndSpecification<T>
       : CompositeSpecification<T>
       where T : class,new()
    {
        #region Members

        private ISpecification<T> _RightSideSpecification = null;
        private ISpecification<T> _LeftSideSpecification = null;

        #endregion

        #region Public Constructor

        /// <summary>
        /// Constructor por defecto para AndSpecification
        /// </summary>
        /// <param name="leftSide">Especificación del lado izquierdo.</param>
        /// <param name="rightSide">Especificación del lado derecho.</param>
        public AndSpecification(ISpecification<T> leftSide, ISpecification<T> rightSide)
        {
            if (leftSide == (ISpecification<T>)null)
                throw new ArgumentNullException("leftSide");

            if (rightSide == (ISpecification<T>)null)
                throw new ArgumentNullException("rightSide");

            this._LeftSideSpecification = leftSide;
            this._RightSideSpecification = rightSide;
        }

        #endregion

        #region Composite Specification overrides

        /// <summary>
        /// Especificación del lado izquierdo.
        /// </summary>
        public override ISpecification<T> LeftSideSpecification
        {
            get
            {
                return _LeftSideSpecification;
            }
        }

        /// <summary>
        /// Especificación del lado derecho.
        /// </summary>
        public override ISpecification<T> RightSideSpecification
        {
            get
            {
                return _RightSideSpecification;
            }
        }

        /// <summary>
        /// <see cref="Domain.Core.ISpecification{T}"/>
        /// </summary>
        /// <returns><see cref="Domain.Core.ISpecification{T}"/></returns>
        public override Expression<Func<T, bool>> SatisfiedBy()
        {
            Expression<Func<T, bool>> left = _LeftSideSpecification.SatisfiedBy();
            Expression<Func<T, bool>> right = _RightSideSpecification.SatisfiedBy();

            return (left.And(right));

        }

        #endregion
    }
}
